/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cafe.adriel.ohosaudioconverter.rxdiffutil.slice;

import berlin.volders.rxdiff2.BaseProvider;
import berlin.volders.rxdiff2.CustomTableLayout;
import berlin.volders.rxdiff2.DiffResult;
import berlin.volders.rxdiff2.Thing;
import berlin.volders.rxdiff2.ThingRepository;
import cafe.adriel.ohosaudioconverter.rxdiffutil.*;
import io.reactivex.rxjava3.disposables.Disposable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.utils.Pair;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static berlin.volders.rxdiff2.DiffResult.calculateDiff;
import static io.reactivex.rxjava3.openharmony.schedulers.OpenHarmonySchedulers.mainThread;
import static io.reactivex.rxjava3.schedulers.Schedulers.computation;

/**
 * 主界面
 *
 * @since 2021-07-05
 */
public class MainAbilitySlice extends AbilitySlice implements CustomTableLayout.ChangeDataListener {
    private static final int FIVE_CHANGE_DATA_TIME = 5;
    private Disposable disposable;
    private MyProvider provider;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
    }

    @Override
    public void onActive() {
        super.onActive();
        CustomTableLayout customTableLayout = new CustomTableLayout(this);
        customTableLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(
                ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_CONTENT));
        DirectionalLayout directionalLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_dl);
        directionalLayout.removeAllComponents();
        directionalLayout.addComponent(customTableLayout);

        customTableLayout.setChangeDataListener(this);
        provider = new MyProvider(LayoutScatter.getInstance(this));
        List<Thing> emptyList = new ArrayList<>();
        Pair<List<Thing>, DiffResult> initialPair = Pair.create(emptyList, null);
        disposable = ThingRepository
                .latestThings(FIVE_CHANGE_DATA_TIME, TimeUnit.SECONDS)
                .scan(initialPair, (pair, next) -> {
                    DiffResult result = calculateDiff();
                    return Pair.create(next, result);
                })
                .skip(1)
                .subscribeOn(computation())
                .observeOn(mainThread())
                .subscribe(listDiffResultPair -> {
                    provider.setThings(listDiffResultPair.f);
                    listDiffResultPair.s.dispatchUpdatesTo(customTableLayout, provider);
                });
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        releaseDisposable();
    }

    @Override
    protected void onBackground() {
        super.onBackground();
        releaseDisposable();
    }

    @Override
    protected void onStop() {
        super.onStop();
        releaseDisposable();
    }

    private void releaseDisposable() {
        if (disposable != null) {
            disposable.dispose();
            disposable = null;
        }
    }

    @Override
    public void changeData(Component component, int position) {
        Text itemText = (Text) component.findComponentById(ResourceTable.Id_list_item_text);
        itemText.setText(provider.getThings().get(position).getText());
        DependentLayout itemDirectionalLayout = (DependentLayout) component
                .findComponentById(ResourceTable.Id_list_item_dl);
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(new RgbColor(new Color(provider.getThings().get(position).getColor()).getValue()));
        itemDirectionalLayout.setBackground(shapeElement);
    }

    /**
     * MyProvider
     *
     * @since 2021-07-05
     */
    private class MyProvider extends BaseProvider {
        private List<Thing> things = new ArrayList<>();
        private LayoutScatter mLayoutScatter;

        MyProvider(LayoutScatter layoutScatter) {
            this.mLayoutScatter = layoutScatter;
        }

        @Override
        public int count() {
            return things.size();
        }

        @Override
        public Component getComponent(int position, Component component, ComponentContainer componentContainer) {
            Component dependentLayout = mLayoutScatter
                    .parse(ResourceTable.Layout_list_item, componentContainer, false);
            Text itemText = (Text) dependentLayout.findComponentById(ResourceTable.Id_list_item_text);
            DependentLayout itemDirectionalLayout = (DependentLayout) dependentLayout
                    .findComponentById(ResourceTable.Id_list_item_dl);
            itemText.setText(things.get(position).getText());
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(new RgbColor(new Color(things.get(position).getColor()).getValue()));
            itemDirectionalLayout.setBackground(shapeElement);
            return dependentLayout;
        }

        public List<Thing> getThings() {
            return things;
        }

        public void setThings(List<Thing> things) {
            if (this.things.size() > 0) {
                this.things.clear();
            }
            this.things = things;
        }
    }
}
